`timescale 1ns/1ns
`include "../verilog/fifo_async.v"
`include "../verilog/dp_ram.v"
`include "../verilog/gen_wr_ptr.v"
`include "../verilog/gen_rd_ptr.v"
`include "../verilog/sync.v"

module fifo_async_tb;

parameter DATA_WIDTH = 16;
parameter ADDR_WIDTH = 4;

reg reset_n;

reg wr_clk;
reg wr_en;
wire [DATA_WIDTH - 1 : 0] wr_data;
wire full;

reg rd_clk;
reg rd_en;
wire [DATA_WIDTH - 1 : 0] rd_data;
wire empty;

reg [DATA_WIDTH - 1 : 0] wr_cnt;

initial begin
	$dumpfile("fifo_async_tb.vcd");
	$dumpvars(0, fifo_async_tb);
	reset_n <= 1'b0;
	#200
	reset_n <= 1'b1;
	#10000
	$display("test complete");
	$finish;
end

initial begin
	wr_clk <= 1'b0;
	// wait 5ns for wr freq of 200 MHz
	forever #5 wr_clk <= ~wr_clk;
end

initial begin
	rd_clk <= 1'b0;
	// wait 10ns for wr freq of 100 MHz
	forever #10 rd_clk <= ~rd_clk;
end

assign wr_data = wr_cnt;

always @(posedge wr_clk) begin
	wr_en <= 1'b0;
	if (reset_n == 1'b1 & full == 1'b0) begin
		wr_en <= 1'b1;
	end

	if (reset_n == 1'b0) begin
		wr_cnt <= 16'b0;
	end else if (wr_en == 1'b1) begin
		wr_cnt <= wr_cnt + 1;
	end
end

always @(posedge rd_clk) begin
	rd_en <= 1'b0;
	if (reset_n == 1'b1 & empty == 1'b0) begin
		rd_en <= 1'b1;
	end
end

fifo_async #(
	.DATA_WIDTH (DATA_WIDTH),
	.ADDR_WIDTH (ADDR_WIDTH)
) fifo_async (
	.reset_n (reset_n),

	.wr_clk(wr_clk),
	.wr_en(wr_en),
	.full(full),
	.wr_data(wr_data),

	.rd_clk(rd_clk),
	.rd_en(rd_en),
	.empty(empty),
	.rd_data(rd_data)
);
endmodule